# def add(first, *second):
#     return first + sum(second)
#
#
# print(add(3))
# print(add(3, 4))
# print(add(3, 4, 5))
# print(add(3, 4, 5, 6))

# 传参时，*args会接收多个参数，如果*args后面还有参数，那后面的参数会作为关键字参数显式传参
# def something(a, *args, b):
#     print('a= ', a)
#     print('args=', args)
#     print('b=', b)
#
#
# something(1, 2, 3, 4, 5, 6, b=7)
# a = 1
#
#
# def func(a1):
#     # global a
#     a1 = 2
#     print(a1)
#
#
# func(a)
# print(a)

# def func(a, *, block=False):
#     if block:
#         print(a, 'block')
#     else:
#         print(a, 'not block')
#
#
# func(1)
# func(2, block=True)

# python没有类型，所以给函数加解注会便于理解
# def add(x: int, y: int) -> int:
#     return x + y


# 返回多个值，一般都是返回一个元组,
# def ret(a, b):
#     c = a + b
#     return a, b, c
#
#
# nums = ret(1, 2)
# print(nums)
# 使用,可以创建一个元组 类似这样：
# arr = 1, 2, 3
# print(arr)


# 函数的参数默认值, 默认值在函数定义的时候指定，并且只会初始化一次
# 默认值给定不可变对象，比如列表，元组，字典，函数，类对象，那么默认值只会初始化一次，如果给定可变对象，那么每次调用函数的时候，都会创建一个新的对象
# def func(a, b=9, c=10):
#     print(a, b, c)
#
#
# func(1)
# func(1, 2)
# func(1, 2, 3)


# 匿名/内联函数lambda
# adds = lambda a, b: a + b
# print(adds(1, 2))
# print(adds(2, 3))

# lambda函数在捕获外部参数时是运行时绑定的，而不是编译时绑定的
# 所以绑定的X是运行时的X值 ！！！
# x = 10
#
# a = lambda y: x + y
#
# x = 20
#
# b = lambda y: x + y
#
# print(a(1))
# print(b(1))

# 使用partial()来减少函数的调用参数
# from functools import partial
#
#
# def sums(a, b, c, d):
#     return a + b + c + d
#
#
# s1 = partial(sums, 1)
# print(s1(2, 3, 4))
# s2 = partial(sums, 1, 2)
# print(s2(30, 40))


# nonlocal关键字用于引用外层函数的变量
# def make_handler():
#     sequence = 0
#
#     def handler(result):
#         nonlocal sequence
#         sequence += 1
#         print('[{}] Got: {}'.format(sequence, result))
#
#     return handler


# def apply_async(func, args, *, callback):
#     # Compute the result
#     result = func(*args)
#
#     # Invoke the callback with the result
#     callback(result)
#
#
# def make_handler():
#     sequence = 0
#     while True:
#         result = yield
#         sequence += 1
#         print('[{}] Got: {}'.format(sequence, result))
#
#
# def add(x, y):
#     return x + y
#
#
# handler = make_handler()
# next(handler)
# apply_async(add, (2, 3), callback=handler.send)
